"""
等深分箱 与 等宽分箱
author:lhc
2021.3
"""


def depth_box(data, depth):
    """
    进行等深分箱，每个箱子样本相同
    :param data: 源数据
    :param depth: 深度/每个箱子内的样本
    :return: 分箱结果  二维list
    """
    box_data = []
    n = int(len(data) / depth)  # 一共能分几个箱子
    data.sort(reverse=False)
    for i in range(n):
        box_data.append(data[i * depth: (i + 1) * depth])
    return box_data


def len_box(data, n):
    """
    进行等宽分箱，每个箱子宽度相同
    :param data: 源数据
    :param n: 箱子个数
    :return: 分箱结果  二维list
    """
    box_data = []
    data.sort(reverse=False)
    num = (data[-1] - data[0]) / n  # 箱子宽度
    pre_data = data[0]
    single_box = []
    for item in data:
        single_box.append(item)
        if item - pre_data > num:
            box_data.append(single_box)
            single_box = []
            pre_data = item
    if len(single_box) != 0:
        box_data.append(single_box)
    return box_data


def avg_smooth(data):
    """
    均值平滑
    :param data: 二维list
    :return: 平滑后 二维list
    """
    from numpy import mean
    smo_data = []
    for item in data:
        avg = round(mean(item), 2)
        smo_data.append([avg for i in range(len(item))])
    return smo_data


def boundary_smooth(data):
    """
    边界平滑
    :param data: 二维list
    :return: 平滑后 二维list
    """
    smo_data = []
    for item in data:
        item.sort(reverse=False)
        single_data = []
        for i in item:
            if abs(i - item[0]) > abs(i - item[-1]):
                single_data.append(item[-1])
            else:
                single_data.append(item[0])
        smo_data.append(single_data)
    return smo_data


if __name__ == '__main__':
    raw_data = [1278, 1808, 2028, 2267, 2268, 2249, 2312, 2107, 2227,
                2048, 2041, 1485, 1394, 1254, 1078, 983, 777, 1046,
                943, 724, 529, 199, 178, 465]

    depth_data = depth_box(raw_data, 4)
    len_data = len_box(raw_data, 4)
    print("The results of equal depth division:", depth_data, end="\n\n")
    print("The results of equal width division:", len_data, end="\n\n")
    print("avg_smooth for equal width boxes:", avg_smooth(len_data), end="\n\n")
    print("boundary_smooth for equal width boxes:", boundary_smooth(len_data), end="\n\n")
